/**
 * Copyright &copy; 2013-2015 山东易科德软件有限公司 All rights reserved.
 */
package cn.net.ecode.modules.sys.security;

import java.util.Map;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.util.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.net.ecode.common.config.Global;
import cn.net.ecode.common.utils.CookieUtils;
import cn.net.ecode.common.utils.IpUtils;
import cn.net.ecode.common.utils.StringUtils;
import cn.net.ecode.common.web.Servlets;
import cn.net.ecode.modules.sys.utils.UserUtils;

import com.google.common.collect.Maps;

/**
 * 表单验证（包含验证码）过滤类
 * @author ThinkGem
 * @version 2014-5-19
 */
public class FormAuthenticationFilter extends org.apache.shiro.web.filter.authc.FormAuthenticationFilter {

    private static final Logger logger = LoggerFactory.getLogger(FormAuthenticationFilter.class);
    
	public static final String DEFAULT_CAPTCHA_PARAM = "validateCode";
	public static final String DEFAULT_PARAMS_PARAM = "params";
	public static final String DEFAULT_MESSAGE_PARAM = "message";
	public static final String DEFAULT_REMEMBER_USERCODE_PARAM = "rememberUserCode";

	private String captchaParam = DEFAULT_CAPTCHA_PARAM;
	private String paramsParam = DEFAULT_PARAMS_PARAM;
	private String messageParam = DEFAULT_MESSAGE_PARAM;
	private String rememberUserCodeParam = DEFAULT_REMEMBER_USERCODE_PARAM;
	
	protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
		String username = getUsername(request);
		String password = getPassword(request);
		if (password==null){
			password = "";
		}
		boolean rememberMe = isRememberMe(request);
		// 记住用户名
		if(WebUtils.isTrue(request, getRememberUserCodeParam())){
			CookieUtils.setCookie((HttpServletResponse)response, "rememberUserCode", username);
		}else{ 
			CookieUtils.setCookie((HttpServletResponse)response, "rememberUserCode", "");
		}
		String host = IpUtils.getRemoteAddr((HttpServletRequest)request);
		String captcha = WebUtils.getCleanParam(request, getCaptchaParam());
		String params = WebUtils.getCleanParam(request, getParamsParam());
		return new UsernamePasswordToken(username, password.toCharArray(), rememberMe, host, captcha, params);
	}

	/**
	 * 验证码
	 * @return
	 */
	public String getCaptchaParam() {
		return captchaParam;
	}

	public void setCaptchaParam(String captchaParam) {
		this.captchaParam = captchaParam;
	}

	/**
	 * 登录附加参数JSON
	 * @return
	 */
	public String getParamsParam() {
		return paramsParam;
	}
	
	public void setParamsParam(String paramsParam) {
		this.paramsParam = paramsParam;
	}

	/**
	 * 登录返回消息
	 * @return
	 */
	public String getMessageParam() {
		return messageParam;
	}

	public void setMessageParam(String messageParam) {
		this.messageParam = messageParam;
	}

	/**
	 * 记住用户名
	 * @return
	 */
	public String getRememberUserCodeParam() {
		return rememberUserCodeParam;
	}
	
	public void setRememberUserCodeParam(String rememberUserCodeParam) {
		this.rememberUserCodeParam = rememberUserCodeParam;
	}

	/**
	 * 是否为登录操作（支持GET登录时传递__login=true参数）
	 */
	@Override
	protected boolean isLoginSubmission(ServletRequest request, ServletResponse response) {
		boolean isLogin = WebUtils.isTrue(request, "__login");
		return super.isLoginSubmission(request, response) || isLogin;
	}
	
	/**
	 * 登录成功调用事件
	 */
	@Override
	protected boolean onLoginSuccess(AuthenticationToken token,
			Subject subject, ServletRequest request, ServletResponse response) throws Exception {
		// 登录操作如果是Ajax操作，直接返回登录信息字符串。
		if (Servlets.isAjaxRequest((HttpServletRequest)request)){
			Map<String, Object> resultMap = Maps.newHashMap();
			resultMap.put("result", Global.TRUE);
			resultMap.put("message", "登录成功！");
			resultMap.put("sessionid", (String)UserUtils.getSession().getId());
			resultMap.put("user", UserUtils.getUser()); // 当前用户信息
			Servlets.renderStringToJsonP((HttpServletResponse)response, resultMap);
			return false;
		}
		// 登录成功直接返回到首页
		else{
			WebUtils.issueRedirect(request, response, getSuccessUrl(), null, true);
			return false;
		}
	}
	
	/**
	 * 登录失败调用事件
	 */
	@Override
	protected boolean onLoginFailure(AuthenticationToken token,
			AuthenticationException e, ServletRequest request, ServletResponse response) {
		String className = e.getClass().getName(), message = "";
		if (IncorrectCredentialsException.class.getName().equals(className)
				|| UnknownAccountException.class.getName().equals(className)){
			message = "账号或密码错误, 请重试.";
		}
		else if (e.getMessage() != null && StringUtils.startsWith(e.getMessage(), "msg:")){
			message = StringUtils.replace(e.getMessage(), "msg:", "");
		}
		else{
			message = "系统出现点问题，请稍后再试！";
			logger.error(message, e); // 输出到日志文件
		}
        request.setAttribute(getFailureKeyAttribute(), className);
        request.setAttribute(getMessageParam(), message);
        return true;
	}
	
}